package com.ruoyi.btlfbreed.controller;

import com.ruoyi.btlfbreed.domain.MChickenGrowthSeriesVO;
import com.ruoyi.btlfbreed.domain.MSelectOptionVO;
import com.ruoyi.btlfbreed.domain.MyTbChickenGrowData;
import com.ruoyi.btlfbreed.domain.MyTbChickenHatchRecordsData;
import com.ruoyi.btlfbreed.domain.MyTbChickenHouses;
import com.ruoyi.btlfbreed.domain.MyTbChickenSalesData;
import com.ruoyi.btlfbreed.domain.MyTbChickensVO;
import com.ruoyi.btlfbreed.domain.TbChickenGrowthRecords;
import com.ruoyi.btlfbreed.domain.TbChickenHouses;
import com.ruoyi.btlfbreed.domain.TbChickens;
import com.ruoyi.btlfbreed.domain.TbCustomers;
import com.ruoyi.btlfbreed.domain.TbFeedInfo;
import com.ruoyi.btlfbreed.domain.TbMedicineInfo;
import com.ruoyi.btlfbreed.domain.TbStockLog;
import com.ruoyi.btlfbreed.domain.TbVaccineInfo;
import com.ruoyi.btlfbreed.service.ITbChickenGrowthRecordsService;
import com.ruoyi.btlfbreed.service.ITbChickenHatchRecordsService;
import com.ruoyi.btlfbreed.service.ITbChickenHousesService;
import com.ruoyi.btlfbreed.service.ITbChickenSalesInfoService;
import com.ruoyi.btlfbreed.service.ITbChickensService;
import com.ruoyi.btlfbreed.service.ITbCustomersService;
import com.ruoyi.btlfbreed.service.ITbFeedInfoService;
import com.ruoyi.btlfbreed.service.ITbMedicineInfoService;
import com.ruoyi.btlfbreed.service.ITbVaccineInfoService;
import com.ruoyi.btlfbreed.utils.MyDateUtils;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.service.ISysUserService;
import io.swagger.annotations.Api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Api("肉鸡系统管理")
@RestController
@RequestMapping("/api")
public class APIController extends BaseController
{
    @Autowired
    private ITbChickenHousesService tbChickenHousesService;
    @Autowired
    private ISysUserService iSysUserService;
    @Autowired
    private ITbChickensService iTbChickensService;

    @Autowired
    private ITbFeedInfoService tbFeedInfoService;

    @Autowired
    private ITbMedicineInfoService tbMedicineInfoService;

    @Autowired
    private ITbVaccineInfoService tbVaccineInfoService;
    @Autowired
    private ITbCustomersService tbCustomersService;
    @Autowired
    private ITbChickenGrowthRecordsService tbChickenGrowthRecordsService;
    @Autowired
    private ITbChickenHatchRecordsService tbChickenHatchRecordsService;
    @Autowired
    private ITbChickenSalesInfoService tbChickenSalesInfoService;

    @GetMapping(value = "/test")
    public String test()
    {
        return "Request test.";
    }


    /**
     * 获取岗位选择框列表
     */
    @GetMapping("/optionSelect")
    public AjaxResult optionSelect()
    {
        List<TbChickenHouses> tbChickenHouses = tbChickenHousesService.selectTbChickenHousesList(new MyTbChickenHouses());
        List<SysUser> users = iSysUserService.selectUserAll();
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("chickenHouses", tbChickenHouses);
        resMap.put("users", users);
        return success(resMap);
    }


    /**
     * 获取岗位选择框列表
     */
    @GetMapping("/optionUserselect")
    public AjaxResult optionUserselect()
    {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysRole> roles = loginUser.getUser().getRoles();
        List<SysUser> users=new ArrayList<>();
        List<SysUser> newusers = new ArrayList<>();
        if (loginUser.getUserId()==1)
        {
            users = iSysUserService.selectUserAll();
            newusers=users;
        }
        else
        {
            users = iSysUserService.selectUserAll();

            for (SysUser item :
                users)
            {
                for (SysRole item2 :
                    roles)
                {
                    List<SysRole> collect = item.getRoles().stream().filter(p -> p.getRoleId() == item2.getRoleId()).collect(Collectors.toList());
                    if (collect != null && collect.size() > 0)
                    {
                        newusers.add(item);
                        break;
                    }

                }
            }
        }

        return success(newusers);
    }

    @GetMapping("/optionCustomerselect")
    public AjaxResult optionCustomerselect()
    {
        List<TbCustomers> tbCustomers = tbCustomersService.selectTbCustomersList(new TbCustomers());
        return success(tbCustomers);
    }


    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor)
    {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    /**
     * 获取肉鸡选择框列表
     */
    @GetMapping("/optionCheckselect")
    public AjaxResult optionCheckselect()
    {
        List<TbChickens> tbChickens = iTbChickensService.selectTbChickensList(new TbChickens());
        List<MSelectOptionVO> res = new ArrayList<>();
        List<TbChickens> n = tbChickens.stream().filter(p -> p.getIsSold().equals("N")).filter(p -> p.getHealthStatus().equals("0") || p.getHealthStatus().equals("1"))
            .collect(Collectors.toList());

        List<TbChickens> collect = n.stream().filter(distinctByKey(TbChickens::getHatchBatchNo)).collect(Collectors.toList());
        for (TbChickens item :
            collect)
        {
            MSelectOptionVO temp = new MSelectOptionVO();
            String hatchBatchNo = item.getHatchBatchNo();
            temp.setLabel(hatchBatchNo);
            List<TbChickens> collect1 = n.stream().filter(p -> p.getHatchBatchNo().equals(hatchBatchNo)).collect(Collectors.toList());
            List<MSelectOptionVO> temp2 = new ArrayList<>();
            for (TbChickens item2 :
                collect1)
            {
                MSelectOptionVO temp3 = new MSelectOptionVO();
                temp3.setLabel(item2.getChickenNo());
                temp3.setValue(item2.getChickenId().toString());
                temp2.add(temp3);
            }
            temp.setOptions(temp2);
            res.add(temp);
        }

        return success(res);
    }

    /**
     * 获取饲料选择框列表
     */
    @GetMapping("/optionFeedselect")
    public AjaxResult optionFeedselect()
    {
        List<TbFeedInfo> tbFeedInfos = tbFeedInfoService.selectTbFeedInfoList(new TbFeedInfo());
        List<MSelectOptionVO> res = new ArrayList<>();
        for (TbFeedInfo item :
            tbFeedInfos)
        {
            MSelectOptionVO temp = new MSelectOptionVO();
            temp.setLabel(item.getFeedName());
            temp.setValue(item.getId().toString());
            res.add(temp);
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        List<SysRole> roles = loginUser.getUser().getRoles();
        List<SysUser> users=new ArrayList<>();
        List<SysUser> newusers = new ArrayList<>();
        if (loginUser.getUserId()==1)
        {
            users = iSysUserService.selectUserAll();
            newusers=users;
        }
        else
        {
            users = iSysUserService.selectUserAll();

            for (SysUser item :
                users)
            {
                for (SysRole item2 :
                    roles)
                {
                    List<SysRole> collect = item.getRoles().stream().filter(p -> p.getRoleId() == item2.getRoleId()).collect(Collectors.toList());
                    if (collect != null && collect.size() > 0)
                    {
                        newusers.add(item);
                        break;
                    }

                }
            }
        }

//        users.stream().filter(p->p.getRoleId())
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("TbFeedInfo", res);
        resMap.put("users", newusers);
        return success(resMap);
    }

    @GetMapping("/getdashboardPanelData")
    public AjaxResult getdashboardPanelData()
    {
        List<TbChickens> tbChickens = iTbChickensService.selectTbChickensList(new TbChickens());

        List<TbFeedInfo> tbFeedInfos = tbFeedInfoService.selectTbFeedInfoList(new TbFeedInfo());
        BigDecimal feedrkNum = BigDecimal.ZERO;
        BigDecimal feedNum = BigDecimal.ZERO;
        BigDecimal feedxhNum = BigDecimal.ZERO;
        BigDecimal gqfeedNum = BigDecimal.ZERO;
        for (TbFeedInfo item :
            tbFeedInfos)
        {
            BigDecimal stockQuantity = item.getStockQuantity();
            BigDecimal out = BigDecimal.ZERO;
            if (item.getTbStockLogList() != null)
            {
                out = item.getTbStockLogList().stream().filter(p -> p.getOperationType().equals("out")).map(TbStockLog::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            feedrkNum = feedrkNum.add(stockQuantity);
            if (stockQuantity.compareTo(out) > 0)
            {
                BigDecimal remain = stockQuantity.subtract(out);
                feedNum = feedNum.add(remain);

                Date expiryDate = item.getExpiryDate();
                Date nowDate = DateUtils.getNowDate();
                Long aLong = MyDateUtils.timeDayDistance(expiryDate, nowDate);
                if (aLong <= 7)
                {
                    gqfeedNum = gqfeedNum.add(remain);

                }
            }

        }
        //消耗数据
        feedxhNum = feedrkNum.subtract(feedNum);
        List<TbMedicineInfo> tbMedicineInfos = tbMedicineInfoService.selectTbMedicineInfoList(new TbMedicineInfo());
        BigDecimal medicinerkNum = BigDecimal.ZERO;
        BigDecimal medicineNum = BigDecimal.ZERO;
        BigDecimal medicinexhNum = BigDecimal.ZERO;
        BigDecimal gqmedicineNum = BigDecimal.ZERO;

        for (TbMedicineInfo item :
            tbMedicineInfos)
        {
            BigDecimal stockQuantity = item.getStockQuantity();
            medicinerkNum = medicinerkNum.add(stockQuantity);
            BigDecimal out = BigDecimal.ZERO;
            if (item.getTbStockLogList() != null)
            {
                out = item.getTbStockLogList().stream().filter(p -> p.getOperationType().equals("out")).map(TbStockLog::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if (stockQuantity.compareTo(out) > 0)
            {
                BigDecimal remain = stockQuantity.subtract(out);
                medicineNum = medicineNum.add(remain);

                Date expiryDate = item.getExpiryDate();
                Date nowDate = DateUtils.getNowDate();
                Long aLong = MyDateUtils.timeDayDistance(expiryDate, nowDate);
                if (aLong <= 7)
                {
                    gqmedicineNum = gqmedicineNum.add(remain);
                }
            }
        }
        medicinexhNum = medicinerkNum.subtract(medicineNum);
        List<TbVaccineInfo> tbVaccineInfos = tbVaccineInfoService.selectTbVaccineInfoList(new TbVaccineInfo());
        BigDecimal vaccinerkNum = BigDecimal.ZERO;
        BigDecimal vaccineNum = BigDecimal.ZERO;
        BigDecimal vaccinexhNum = BigDecimal.ZERO;

        BigDecimal gqvaccineNum = BigDecimal.ZERO;

        for (TbVaccineInfo item :
            tbVaccineInfos)
        {
            BigDecimal stockQuantity = item.getStockQuantity();
            BigDecimal out = BigDecimal.ZERO;
            vaccinerkNum = vaccinerkNum.add(stockQuantity);
            if (item.getTbStockLogList() != null)
            {
                out = item.getTbStockLogList().stream().filter(p -> p.getOperationType().equals("out")).map(TbStockLog::getQuantity)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            }
            if (stockQuantity.compareTo(out) > 0)
            {
                BigDecimal remain = stockQuantity.subtract(out);
                vaccineNum = vaccineNum.add(remain);

                Date expiryDate = item.getExpiryDate();
                Date nowDate = DateUtils.getNowDate();
                Long aLong = MyDateUtils.timeDayDistance(expiryDate, nowDate);
                if (aLong <= 7)
                {
                    gqvaccineNum = gqvaccineNum.add(remain);
                }
            }
        }
        vaccinexhNum = vaccinerkNum.subtract(vaccineNum);
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("chickens", tbChickens.size());
        resMap.put("feedNum", feedNum.doubleValue());
        resMap.put("gqfeedNum", gqfeedNum.doubleValue());
        resMap.put("medicineNum", medicineNum.doubleValue());
        resMap.put("gqmedicineNum", gqmedicineNum.doubleValue());
        resMap.put("vaccineNum", vaccineNum.doubleValue());
        resMap.put("feedxhNum", feedxhNum.doubleValue());
        resMap.put("medicinexhNum", medicinexhNum.doubleValue());
        resMap.put("vaccinexhNum", vaccinexhNum.doubleValue());
        resMap.put("feedrkNum", feedrkNum.doubleValue());
        resMap.put("medicinerkNum", medicinerkNum.doubleValue());
        resMap.put("vaccinerkNum", vaccinerkNum.doubleValue());

        return success(resMap);
    }


    @GetMapping("/getMonthSumGrowData")
    public AjaxResult getMonthSumGrowData(@RequestParam String year, @RequestParam String chickenNo)
    {

        List<MyTbChickenGrowData> monthAvgGrowData = tbChickenGrowthRecordsService.getMonthAvgGrowData(year);
        List<MyTbChickenGrowData> monthData = new ArrayList<>();
        List<MyTbChickenGrowData> monthAvgData = new ArrayList<>();

        List<MChickenGrowthSeriesVO> resList = new ArrayList<>();
        if (chickenNo != "")
        {
            List<MyTbChickenGrowData> monthSumGrowData = tbChickenGrowthRecordsService.getMonthSumGrowData(year, chickenNo);
            MChickenGrowthSeriesVO sumData = new MChickenGrowthSeriesVO();
            MChickenGrowthSeriesVO avgData = new MChickenGrowthSeriesVO();
            sumData.setName(chickenNo);
            sumData.setType("line");
            sumData.setStack("Total");
            sumData.setData(new Double[12]);
            avgData.setName("avgData");
            avgData.setType("line");
            avgData.setStack("Total");
            avgData.setData(new Double[12]);
            for (int i = 1; i < 13; i++)
            {

                MyTbChickenGrowData temp = new MyTbChickenGrowData();
                temp.setYear(year);
                sumData.getData()[i - 1] = null;
                avgData.getData()[i - 1] = null;
                int finalI = i;
                temp.setMonth(finalI + "");
                List<MyTbChickenGrowData> collect = monthSumGrowData.stream().filter(p -> p.getMonth().equals(finalI + "")).collect(Collectors.toList());
                if (collect != null && collect.size() > 0)
                {
                    MyTbChickenGrowData myTbChickenGrowData = collect.get(0);
                    temp.setWeight(myTbChickenGrowData.getWeight());
                    sumData.getData()[i - 1] = myTbChickenGrowData.getWeight();

                    temp.setFeedConsumption(myTbChickenGrowData.getFeedConsumption());
                }
                monthData.add(temp);
                temp = new MyTbChickenGrowData();

                temp.setYear(year);

                temp.setMonth(finalI + "");
                collect = monthAvgGrowData.stream().filter(p -> p.getMonth().equals(finalI + "")).collect(Collectors.toList());
                if (collect != null && collect.size() > 0)
                {
                    MyTbChickenGrowData myTbChickenGrowData = collect.get(0);
                    temp.setWeight(myTbChickenGrowData.getWeight());
                    avgData.getData()[i - 1] = myTbChickenGrowData.getWeight();
                    temp.setFeedConsumption(myTbChickenGrowData.getFeedConsumption());
                }
                monthAvgData.add(temp);
            }
            resList.add(sumData);
            resList.add(avgData);
        }


        Map<String, Object> resMap = new HashMap<>();
        resMap.put("avgGrowData", monthAvgGrowData);
        resMap.put("sumMonthGrowData", monthData);
        resMap.put("resList", resList);
        return success(resMap);
    }

    @GetMapping("/getYearChickenHatchData")
    public AjaxResult getYearChickenHatchData()
    {
        List<MyTbChickenHatchRecordsData> yearHatchData = tbChickenHatchRecordsService.getYearHatchData();
        String[] years = new String[yearHatchData.size()];
        Double[] hatchRate = new Double[yearHatchData.size()];
        Double[] mortalityRate = new Double[yearHatchData.size()];


        Map<String, Object> seriesData = new HashMap<>();
        for (int i = 0; i < yearHatchData.size(); i++)
        {
            MyTbChickenHatchRecordsData myTbChickenHatchRecordsData = yearHatchData.get(i);
            years[i] = myTbChickenHatchRecordsData.getYear();

            hatchRate[i] = myTbChickenHatchRecordsData.getHatchRate();
            mortalityRate[i] = myTbChickenHatchRecordsData.getMortalityRate();
        }
        seriesData.put("hatchRate", hatchRate);
        seriesData.put("mortalityRate", mortalityRate);

        Map<String, Object> resMap = new HashMap<>();
        resMap.put("xAxisData", years);
        resMap.put("hatchRate", hatchRate);
        resMap.put("mortalityRate", mortalityRate);
        return success(resMap);

    }

    @GetMapping("/getChickenData")
    public AjaxResult getChickenData(@RequestParam String chickenId)
    {
        List<MyTbChickensVO> chickenData = iTbChickensService.getChickenData(chickenId);
        String[] xAxisData = new String[chickenData.size()];
        List<Map<String, Object>> resList = new ArrayList<>();
        for (int i = 0; i < chickenData.size(); i++)
        {
            MyTbChickensVO myTbChickensVO = chickenData.get(i);
            xAxisData[i] = myTbChickensVO.getSdate();
//            Map<String, Object> temp=new HashMap<>();
//            temp.put(myTbChickensVO.getSdate(),myTbChickensVO.getCount());
//            resList.add(temp);

        }


        Stream<String> distinct = Arrays.stream(xAxisData).distinct();
        Object[] objects = distinct.toArray();
        List<MChickenGrowthSeriesVO> resList2 = new ArrayList<>();

        for (int j = 1; j < 7; j++)
        {
            String d = j + "";
            List<MyTbChickensVO> collect = chickenData.stream().filter(p -> p.getType().equals(d)).collect(Collectors.toList());
            if (collect != null && collect.size() > 0)
            {
                MChickenGrowthSeriesVO temp = new MChickenGrowthSeriesVO();
                temp.setName(collect.get(0).getSjname());
                temp.setType("line");
                temp.setStack("Total");
                Double[] tempData=new Double[objects.length];
                for (int i = 0; i < objects.length; i++)
                {
                    String s = objects[i].toString();

                    for (MyTbChickensVO item :
                        collect)
                    {
//                        objects
                     if (item.getSdate().equals(s)){
                         tempData[i]= Double.valueOf(item.getCount());
                     }
//                     else
//                     {
//                         tempData[i]=null;
//                     }

//                        boolean found = Arrays.stream(objects)
//                            .anyMatch(dd -> dd.equals(item.getSdate()));
//                        if (found)
//                        {
//                            tempData[i]= Double.valueOf(item.getCount());
//                            break;
//                        }
                    }

                }



                temp.setData(tempData);
                resList2.add(temp);
            }
        }


        Map<String, Object> resMap = new HashMap<>();
        resMap.put("xAxisData", objects);
        resMap.put("resList", resList2);

        return success(resMap);

    }


    @GetMapping("/getMonthSalesData")
    public AjaxResult getMonthSalesData(@RequestParam String year, @RequestParam String month)
    {
        List<MyTbChickenSalesData> monthSalesData = tbChickenSalesInfoService.getMonthSalesData(year, month);
        List<Map<String, Object>> resxAxisData = new ArrayList<>();
        for (MyTbChickenSalesData item :
            monthSalesData)
        {
            Map<String, Object> resMap = new HashMap<>();
            resMap.put("saleAmount", item.getSaleAmount());
            resMap.put("saleCostAmount", item.getSaleCostAmount());
            resxAxisData.add(resMap);
        }

        Map<String, Object> resMap = new HashMap<>();
        resMap.put("seriesData", resxAxisData);
        return success(resMap);

    }

    @GetMapping("/optionMedicineInfoselect")
    public AjaxResult optionMedicineInfoselect()
    {
        List<TbMedicineInfo> info = tbMedicineInfoService.selectTbMedicineInfoList(new TbMedicineInfo());
        List<MSelectOptionVO> res = new ArrayList<>();
        for (TbMedicineInfo item :
            info)
        {
            MSelectOptionVO temp = new MSelectOptionVO();
            temp.setLabel(item.getMedicineName());
            temp.setValue(item.getId().toString());
            res.add(temp);
        }
        List<SysUser> users = iSysUserService.selectUserAll();
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("Info", res);
        resMap.put("users", users);

        return success(resMap);
    }

    @GetMapping("/optionVaccineInfoselect")
    public AjaxResult optionVaccineInfoselect()
    {
        List<TbVaccineInfo> info = tbVaccineInfoService.selectTbVaccineInfoList(new TbVaccineInfo());
        List<MSelectOptionVO> res = new ArrayList<>();
        for (TbVaccineInfo item :
            info)
        {
            MSelectOptionVO temp = new MSelectOptionVO();
            temp.setLabel(item.getVaccineName());
            temp.setValue(item.getId().toString());
            res.add(temp);
        }
        List<SysUser> users = iSysUserService.selectUserAll();
        Map<String, Object> resMap = new HashMap<>();
        resMap.put("Info", res);
        resMap.put("users", users);
        return success(resMap);
    }

}
